## Warning: We recommend using the dplyr::*_join() family of functions instead.
## Warning: `group_by_()` was deprecated in dplyr 0.7.0.
## Please use `group_by()` instead.
## See vignette('programming') for more help
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
## Warning: sf layer has inconsistent datum (+proj=longlat +datum=NAD83 +no_defs).
## Need '+proj=longlat +datum=WGS84'
## Warning: We recommend using the dplyr::*_join() family of functions instead.
## Warning: sf layer has inconsistent datum (+proj=longlat +datum=NAD83 +no_defs).
## Need '+proj=longlat +datum=WGS84'
## `summarise()` has grouped output by 'county'. You can override using the
## `.groups` argument.
acs_hud_de_geojoined_prop <- acs_hud_de_geojoined %>%
# Calculate difference eligible renters
mutate(diff_30_50 = eligible_renters - eligible_renters_50pct) %>%
rowwise() %>%
mutate(rent_30to40 = sum(rent_30E, rent_35E, rent_40E),
rent_50 = rent_50E) %>%
ungroup %>%
# calculate proportions
mutate(rent_30to40_prop = rent_30to40 / renter_householdersE,
rent_50_prop = rent_50 / renter_householdersE) %>%
mutate(eligible_renters_30pct_prop = eligible_renters / renter_householdersE,
eligible_renters_50pct_prop = eligible_renters_50pct / renter_householdersE,
diff_prop_30_50 = eligible_renters_30pct_prop - eligible_renters_50pct_prop)
scatter_30_50 <- acs_hud_de_geojoined_prop %>%
ggplot(aes(x = eligible_renters, y = eligible_renters_50pct,
label = census_tract_label, color = diff_30_50)) +
geom_smooth(method = "lm") +
geom_point() +
xlab("Households paying 30%+ on rent") +
ylab("Households paying 50%+ on rent")
ggplotly(scatter_30_50)
## `geom_smooth()` using formula 'y ~ x'
barplot_30_50_diff <- acs_hud_de_geojoined_prop %>%
ggplot(aes(x = reorder(tract, diff_30_50), y = diff_30_50)) +
geom_bar(stat = "identity") +
xlab("Census Tracts") +
ylab("Difference between 30% vs 50%")
barplot_30_50_diff %>% ggplotly()
library(broom)
acs_hud_de_geojoined_prop <- acs_hud_de_geojoined_prop %>%
mutate(row_number = row_number() %>% as.character())
scatter_50_30_prop <- acs_hud_de_geojoined_prop %>%
ggplot(aes(x = eligible_renters_30pct_prop, y = eligible_renters_50pct_prop,
label = census_tract_label, color = diff_prop_30_50)) +
geom_smooth(method = "lm") +
geom_point() +
xlab("Proportions of households paying 30%+ on rent") +
ylab("Proportions of households paying 50%+ on rent")
scatter_50_30_prop %>% ggplotly()
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 4 rows containing non-finite values (stat_smooth).
# 50 ~ 30
lm_50_30 <- acs_hud_de_geojoined_prop %>%
lm(data = ., eligible_renters_50pct_prop ~ eligible_renters_30pct_prop)
aug_50_30 <- lm_50_30 %>%
augment()
resid_plot_50_30 <- aug_50_30 %>%
left_join(acs_hud_de_geojoined_prop %>% select(row_number, tract),
by = c(".rownames" = "row_number")) %>%
ggplot(aes(x = eligible_renters_30pct_prop, y = .std.resid, label = tract)) +
geom_point() +
geom_hline(yintercept = 0) +
ylab("Standardized Residual") +
xlab("Proportion of renters paying 30%+ on rent")
resid_plot_50_30 %>%
ggplotly()
scatter_30_50_prop <- scatter_50_30_prop +
coord_flip()
scatter_30_50_prop %>% ggplotly()
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 4 rows containing non-finite values (stat_smooth).
# 30 ~ 50
lm_30_50 <- acs_hud_de_geojoined_prop %>%
lm(data = ., eligible_renters_30pct_prop ~ eligible_renters_50pct_prop)
aug_30_50 <- lm_30_50 %>%
augment()
resid_plot_30_50 <- aug_30_50 %>%
left_join(acs_hud_de_geojoined_prop %>% select(row_number, tract),
by = c(".rownames" = "row_number")) %>%
ggplot(aes(x = eligible_renters_50pct_prop, y = .std.resid, label = tract)) +
geom_point() +
geom_hline(yintercept = 0) +
ylab("Standardized Residual") +
xlab("Proportion of renters paying 50%+ on rent")
resid_plot_30_50 %>%
ggplotly()
barplot_30_50_prop_diff <- acs_hud_de_geojoined_prop %>%
ggplot(aes(x = reorder(tract, diff_prop_30_50), y = diff_prop_30_50)) +
geom_hline(yintercept = mean(acs_hud_de_geojoined_prop$diff_prop_30_50, na.rm = TRUE)) +
geom_bar(stat = "identity") +
xlab("Census Tracts") +
ylab("Difference between 30% vs 50% (proportions)")
barplot_30_50_prop_diff %>% ggplotly()
## Warning: Removed 4 rows containing missing values (position_stack).
Higher numbers mean that the census tract has higher proportions of renters paying 30% or more income on rent than those paying 50% or more income on rent.
I ran a regression predicting the proportion of eligible renters receiving a voucher (voucher serviceability) from the proportion of renters paying 30-40% of rent and the proportion of renters paying 50% or more on rent.
Results showed that:
Higher proportions of non-severely burdened renters (30-40% on rent) and severely-burdened renters (50%+ on rent) were both associated with lower voucher serviceability
There was an interaction between the proportions of non-severe burdened renters and severely burdened renters
Among the census tracts with lower proportion of non-severe burdened renters, higher proportion of severely burdened renters predicted lower proportions of eligible renters receiving a voucher (lower serviceability).
However, among the census tracts with higher proportions of non-severely burdened renters, higher proportions of severely burdened renters predicted higher voucher serviceability.
model <- acs_hud_de_geojoined_prop %>%
lm(data = ., formula = prop_serviced ~ rent_50_prop * rent_30to40_prop)
summary(model)
##
## Call:
## lm(formula = prop_serviced ~ rent_50_prop * rent_30to40_prop,
## data = .)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.20442 -0.09208 -0.04287 0.05029 0.57459
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.47596 0.06081 7.827 6.76e-13 ***
## rent_50_prop -2.21184 0.58543 -3.778 0.000223 ***
## rent_30to40_prop -3.35719 0.64971 -5.167 7.08e-07 ***
## rent_50_prop:rent_30to40_prop 22.08215 6.25155 3.532 0.000540 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1469 on 158 degrees of freedom
## (55 observations deleted due to missingness)
## Multiple R-squared: 0.1808, Adjusted R-squared: 0.1653
## F-statistic: 11.63 on 3 and 158 DF, p-value: 6.321e-07
library(sjPlot)
plot_model(model, type = "int", mdrt.values = "meansd")
acs_hud_de_geojoined_prop %>%
ggplot(aes(x = rent_50_prop, y = prop_serviced)) +
geom_point()
## Warning: Removed 55 rows containing missing values (geom_point).
scatter_nonsevere_severe <- acs_hud_de_geojoined_prop %>%
ggplot(aes(x = rent_30to40_prop, y = rent_50_prop, label = census_tract_label)) +
geom_point()
scatter_nonsevere_severe %>% ggplotly()
acs_hud_de_geojoined_prop %>%
ggplot(aes(x = rent_30to40_prop, y = prop_serviced, label = census_tract_label)) +
geom_point()
## Warning: Removed 55 rows containing missing values (geom_point).
acs_hud_de_geojoined_prop %>%
ggplot(aes(x = rent_50_prop, y = prop_serviced, label = census_tract_label)) +
geom_point()
## Warning: Removed 55 rows containing missing values (geom_point).
scatter_30_50_voucher <- acs_hud_de_geojoined_prop %>%
ggplot(aes(x = prop_serviced, y = diff_prop_30_50, label = tract)) +
geom_point() +
xlab("Proportion of eligible renters receiving a voucher") +
ylab("Difference between 30% vs 50% (proportions)")
scatter_30_50_voucher %>% ggplotly()